﻿

''' <summary>
''' xText Codec as defined in Section 4 of RFC3461.
''' Any ASCII char between "!" (33) and "~" (126) inclusive, except for "+" and "=" is left as it is; 
''' Any chars that do not appear in this range are encoded as +XX where XX are Hexadecimal digits of them.
''' </summary>
Public Module XTextCodec

    'Encode
    ''' <summary>
    ''' Encodes a given US-ASCII String to its xtext form.
    ''' </summary>
    ''' <param name="sourceString">source string to encode.</param>
    ''' <param name="sourceEncoding">source string text encoding.</param>
    Public Function Encode(ByVal sourceString As String, ByVal sourceEncoding As Text.Encoding) As String
        Dim result As String = ""
        Dim sourceBytes As Byte() = sourceEncoding.GetBytes(sourceString)
        For Each b As Byte In sourceBytes
            If b >= 33 AndAlso b <= 126 AndAlso b <> 43 AndAlso b <> 61 Then
                result &= Chr(b)
            Else
                result &= String.Format("+{0:X2}", b)
            End If
        Next
        Return result
    End Function

    'Decode
    ''' <summary>
    ''' Decodes a given xString to its corresponding US-ASCII string.
    ''' </summary>
    ''' <param name="xString">xString encoded as xtext.</param>
    Public Function Decode(ByVal xString As String, ByVal resultEncoding As Text.Encoding) As String
        Dim resultBytes As New List(Of Byte)
        Dim ca As Char() = xString.ToCharArray
        For i As Integer = 0 To ca.Length - 1
            If ca(i) <> "+"c Then
                resultBytes.Add(System.Convert.ToByte(ca(i)))
            Else
                Dim hs As String = ca(i + 1) & ca(i + 2)
                resultBytes.Add(System.Convert.ToByte(hs, 16))
                i += 2
            End If
        Next
        Return resultEncoding.GetString(resultBytes.ToArray)
    End Function
    
End Module
